/**
 * Draw labeled connected components
 */

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;

int main(int argc, char** argv){
    cv::Mat img, img_edge, img_color, labels, stats, centroid;

    if (argc != 2 || (img = cv::imread(argv[1], cv::IMREAD_GRAYSCALE)).empty()){
        cout << "\nExample draw connected components\n"
            << "Call is:\n" << argv[0] << " <image>\n";
        return -1;
    }

    cv::threshold(img, img_edge, 128, 255, cv::THRESH_BINARY);
    cv::imshow("Image after threshold", img_edge);
        cout << "size: " << img_edge.size() << endl;

    int i, nccomps = cv::connectedComponentsWithStats(img_edge, labels, stats, centroid);
    cout << "Total Connected Components Detected: " << nccomps << endl;

    vector<cv::Vec3b> colors(nccomps+1);
    colors[0] = cv::Vec3b(0, 0, 0);     // background pixel remain black
    for (i = 1; i <= nccomps; i++) {
        colors[i] = cv::Vec3b(rand()%256, rand()%256, rand()%256);
        if (stats.at<int>(i-1, cv::CC_STAT_AREA) < 100) {
            colors[i] = cv::Vec3b(0, 0, 0);         // small regions are painted with black too
        }
    }

    img_color = cv::Mat::zeros(img.size(), CV_8UC3);
    for (int y = 0; y < img_color.rows; y++) {
        for (int x = 0; x < img_color.cols; x++) {
            int label = labels.at<int>(y, x);
            CV_Assert(0 <= label && label <= nccomps);
            img_color.at<cv::Vec3b>(y,x) = colors[label];
        }
    }

    cv::imshow("Labeled Map", img_color);
    cv::waitKey(0);

    return 0;
}